home *** CD-ROM | disk | FTP | other *** search
/ BCI NET 2 / BCI NET 2.iso / archives / programming / languages / fpl-v115.lha / FPL / src / caller.c next >
Encoding:
C/C++ Source or Header  |  1995-03-09  |  16.3 KB  |  591 lines

  1. /******************************************************************************
  2.  *                   FREXX PROGRAMMING LANGUAGE                  *
  3.  ******************************************************************************
  4.  
  5.  caller.c
  6.  
  7.  For FPL debugging...
  8.  Only part of the executable file version of FPL.
  9.  
  10.  *****************************************************************************/
  11.  
  12. /************************************************************************
  13.  *                                                                      *
  14.  * fpl.library - A shared library interpreting script langauge.         *
  15.  * Copyright (C) 1992-1994 FrexxWare                                    *
  16.  * Author: Daniel Stenberg                                              *
  17.  *                                                                      *
  18.  * This program is free software; you may redistribute for non          *
  19.  * commercial purposes only. Commercial programs must have a written    *
  20.  * permission from the author to use FPL. FPL is *NOT* public domain!   *
  21.  * Any provided source code is only for reference and for assurance     *
  22.  * that users should be able to compile FPL on any operating system     *
  23.  * he/she wants to use it in!                                           *
  24.  *                                                                      *
  25.  * You may not change, resource, patch files or in any way reverse      *
  26.  * engineer anything in the FPL package.                                *
  27.  *                                                                      *
  28.  * This program is distributed in the hope that it will be useful,      *
  29.  * but WITHOUT ANY WARRANTY; without even the implied warranty of       *
  30.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                 *
  31.  *                                                                      *
  32.  * Daniel Stenberg                                                      *
  33.  * Ankdammsgatan 36, 4tr                                                *
  34.  * S-171 43 Solna                                                       *
  35.  * Sweden                                                               *
  36.  *                                                                      *
  37.  * FidoNet 2:201/328    email:dast@sth.frontec.se                       *
  38.  *                                                                      *
  39.  ************************************************************************/
  40.  
  41.  
  42. #include "FPL.h"
  43. #include "reference.h"        /* should be <FPL/reference.h> */
  44.  
  45. #ifdef AMIGA
  46. #include <exec/types.h>
  47. #include <proto/exec.h>
  48.  
  49. int CXBRK(void) { return(0); }  /* Disable Lattice/SAS CTRL/C handling */
  50. int chkabort(void) { return(0); }  /* really */
  51. #ifdef SHARED
  52. #include <exec/libraries.h>
  53. #include <libraries/dos.h>
  54.  
  55. #include "/include/pragmas/FPL_pragmas.h"
  56. #include "/include/clib/FPL_protos.h"
  57. struct Library *FPLBase = NULL;
  58. #endif
  59.  
  60. #define REG(x) register __ ## x
  61.  
  62. #elif defined(UNIX) /* #ifdef AMIGA */
  63. #include <sys/types.h>
  64.  
  65. #if defined(__GCC_NEW_VARARGS__) /* && defined(__GCC__) */
  66. /*
  67.  * If you want this file to be compiled using the va_* macros instead of the
  68.  * dirty "address of parameter version", define as below!
  69.  * (Without this define, SunOS 4.1.x versions will likely crash!)
  70.  */
  71.  
  72. #define VARARG_FUNCTIONS /* should be defined before the includes below */
  73. #endif
  74.  
  75.  
  76. #define REG(x)
  77. #define TRUE  1
  78. #define FALSE 0
  79. #include "../include/clib/FPL_protos.h"
  80.  
  81. #endif
  82.  
  83. #include <stdlib.h>
  84. #include <string.h>
  85. #include <stdio.h>
  86. #include <stdarg.h>
  87.  
  88. #if defined(AMIGA) && defined(SHARED)
  89. #define CALLER __saveds
  90. #define ASM __asm
  91. #else
  92. #define CALLER
  93. #define ASM
  94. #endif
  95.  
  96. long ASM func(REG(a0) struct fplArgument *);
  97. long ASM inter(REG(a0) void *);
  98. void CALLER ASM MyFree(REG(a1) void *, REG(d0) long);
  99. void CALLER ASM *MyAlloc(REG(d0) long);
  100. long ASM newline(REG(a0) void *);
  101.  
  102. int memory_counter=0;
  103. int maxmemory_counter=0;
  104. int mallocs=0;
  105.  
  106. int newlines=0;
  107.  
  108. enum myfunctions {
  109.   FN_GETINT,
  110.   FN_GETSTRING,
  111.   FN_OUTPUT,
  112.   FN_EXECUTE,
  113.   FN_PRINTF,
  114.   FN_TEST,
  115.   FN_OPENL,
  116.   FN_CLOSEL,
  117.  
  118.   VR_TEST /* first variable ever! */
  119.  
  120.   };
  121.  
  122.  
  123.  
  124. /**********************************************************************
  125.  *
  126.  * int main(int, char **)
  127.  *
  128.  * This function is not included in the run time library version.
  129.  *
  130.  ******/
  131.  
  132. void *key;
  133.  
  134. int main(int argc, char **argv)
  135. {
  136.   long n, end=0;
  137.   long count=0;
  138.   int pre_mallocs;
  139.   long pre_malloc;
  140.   struct fplSymbol *symbols;
  141.   long i;
  142.  
  143.  
  144. #if defined(SHARED) && defined(AMIGA)
  145.   if(!(FPLBase=OpenLibrary(FPLNAME, 5))) {
  146.     printf("Error opening %s!\n", FPLNAME);
  147.     return(-1);
  148.   }
  149.   printf("--> %s\n", FPLBase->lib_IdString);
  150. #endif
  151.  
  152.   if(argc<2) {
  153.     printf("Usage: SFPL <FPL program file name>\n");
  154. #if defined(AMIGA) && defined(SHARED)
  155.     CloseLibrary((struct Library *)FPLBase);
  156. #endif
  157.     return 0;
  158.   }
  159.  
  160.   key=fplInitTags(func,
  161.           FPLTAG_INTERVAL, (unsigned long)inter, /* interval func */
  162.           FPLTAG_USERDATA, (unsigned long)&count, /* user data */
  163. /*          FPLTAG_INTERNAL_DEALLOC, (unsigned long)MyFree,
  164.           FPLTAG_INTERNAL_ALLOC, (unsigned long)MyAlloc, */
  165.           FPLTAG_MINSTACK, 7000,
  166.           FPLTAG_CACHEALLFILES, FPLCACHE_EXPORTS,
  167.                   FPLTAG_REREAD_CHANGES, TRUE,
  168.                   FPLTAG_IDENTITY, argv[0], /* identify us! */
  169.           FPLTAG_DEBUG, TRUE,  /* run in debug mode! */
  170.           FPLTAG_DONE);
  171.  
  172.   
  173.   fplAddFunction(key, "getint",    FN_GETINT,    'I', "s", NULL);
  174.   fplAddFunction(key, "getstring", FN_GETSTRING, 'S', "s", NULL);
  175.   fplAddFunction(key, "output",       FN_OUTPUT,    'I', "O", NULL);
  176.   fplAddFunction(key, "executeFPL",FN_EXECUTE,   'I', "S", NULL);
  177.   fplAddFunction(key, "printf",    FN_PRINTF,    'I', "So>", NULL);
  178.   fplAddFunction(key, "array",     FN_TEST,      'I', "R", NULL);  
  179.  
  180.   fplAddVariable(key, "_TEST_",    VR_TEST,      'S', "default", NULL);
  181.  
  182.   pre_mallocs=mallocs;
  183.   pre_malloc=memory_counter;
  184.  
  185. #if 1
  186.   if(!end && argc>1) {
  187.     int i;
  188.     for(i=1; i<argc; i++) {
  189.       char *string=NULL;
  190.       end=fplExecuteFileTags(key, argv[1],
  191.                              FPLTAG_STRING_RETURN, &string,
  192.                              FPLTAG_DONE);
  193.       if(string) {
  194.         printf("The '%s' program returned '%s'\n", argv[i], string);
  195.         fplFreeString(key, string);
  196.       }
  197.     }
  198.   }
  199. #else
  200.   {
  201.     char *program1 =
  202.       "string lastsearch;\n export void tut(void) {string test; test = lastsearch;} }";
  203.     fplExecuteScriptTags(key, &program1, 1,
  204.                          FPLTAG_KIDNAP_CACHED, TRUE,
  205.                          FPLTAG_CACHEFILE, FPLCACHE_EXPORTS,
  206.                          FPLTAG_PROGNAME, "program1",
  207.                          FPLTAG_DONE);
  208.     program1 = "tut(); ";
  209.     fplExecuteScriptTags(key, &program1, 1,
  210.                          FPLTAG_DONE);
  211.   }
  212. #endif
  213.  
  214. #if 0  
  215.   fplSendTags(key, FPLSEND_GETSYMBOL_FUNCTIONS, &symbols, FPLSEND_DONE);
  216.   printf("\n---------------------\nAll exported functions:\n");
  217.   for(i=0; i<symbols->num; i++)
  218.     printf("%s ", symbols->array[i]);
  219.   fplSendTags(key, FPLSEND_GETSYMBOL_FREE, symbols, FPLSEND_DONE);
  220.  
  221.   fplSendTags(key, FPLSEND_GETSYMBOL_VARIABLES, &symbols, FPLSEND_DONE);
  222.   printf("\n---------------------\nAll exported variables:\n");
  223.   for(i=0; i<symbols->num; i++)
  224.     printf("%s ", symbols->array[i]);
  225.   fplSendTags(key, FPLSEND_GETSYMBOL_FREE, symbols, FPLSEND_DONE);
  226.  
  227.   fplSendTags(key, FPLSEND_GETSYMBOL_CACHEDFILES, &symbols, FPLSEND_DONE);
  228.   printf("\n---------------------\nAll cached files:\n");
  229.   for(i=0; i<symbols->num; i++)
  230.     printf("%s ", symbols->array[i]);
  231.   fplSendTags(key, FPLSEND_GETSYMBOL_FREE, symbols, FPLSEND_DONE);
  232. #endif
  233.  
  234.   fplSendTags(key,
  235.           FPLSEND_GETRETURNCODE, &n,
  236.           FPLSEND_FLUSHFILE, 0,
  237.           FPLSEND_FLUSHCACHE, 1,
  238.           FPLSEND_DONE);
  239.  
  240.   fplFree(key); /* free all shit FPL uses internally */
  241.  
  242. #if defined(AMIGA) && defined(SHARED)
  243.   CloseLibrary((struct Library *)FPLBase);
  244. #endif
  245.  
  246. #ifdef DEBUG_INFO  
  247.   printf("\n-----------------------------------------\n");
  248.   printf("Return code   :  %d\n", n);
  249.   printf("Interval func :  %d\n", count);
  250.   printf("Newlines      :  %d\n", newlines);
  251.   printf("Pre mallocs   :  %d\n", pre_mallocs);
  252.   printf("Pre memory use:  %d\n", pre_malloc);
  253.   printf("Malloc        :  %d\n", mallocs-pre_mallocs);
  254.   printf("memory use    :  %d\n", maxmemory_counter-pre_malloc);
  255.   printf("-----------------------------------------\n");
  256. #endif
  257.  
  258.   if(memory_counter)
  259.     printf(">ALARM!!< Not freed mem :  %d bytes!\n", memory_counter);
  260.  
  261.   return end;
  262. }
  263.  
  264. #ifndef AMIGA /* if not using SAS/C on Amiga */
  265.  
  266. /******************************************************/
  267. /* Parameter list frontends of the library functions: */
  268. /******************************************************/
  269.  
  270. #ifdef VARARG_FUNCTIONS
  271.  
  272. /*
  273.  * The following stub functions to the actual library functions was done
  274.  * to make this run under SunOS 4.1.x using gcc. Thanks to Bernd Noll
  275.  * (b_noll@sun.rhrk.un) for this contribution!
  276.  */
  277.  
  278. long fplExecuteScriptTags(void *anchor, char **program, long lines, ...)
  279. {
  280.   va_list tags;
  281.   long ret;
  282.   va_start(tags, lines); /* get parameter list */
  283.   ret = fplExecuteScript(anchor, program, lines, (unsigned long *)tags);
  284.   va_end(tags)
  285.   return ret;
  286. }
  287.  
  288. long fplExecuteFileTags(void *anchor, char *program, ...)
  289. {
  290.   va_list tags;
  291.   long ret;
  292.   va_start(tags, program); /* get parameter list */
  293.   ret = fplExecuteFile(anchor, program, (unsigned long *)tags);
  294.   va_end(tags)
  295.   return ret;
  296. }
  297.  
  298. void *fplInitTags(long (*func)(struct fplArgument *), ...)
  299. {
  300.   va_list tags;
  301.   void *ret;
  302.   va_start(tags, func); /* get parameter list */
  303.   ret = fplInit(func, (unsigned long *)tags);
  304.   va_end(tags)
  305.   return ret;
  306. }
  307.  
  308. long fplResetTags(void *anchor, ...)
  309. {
  310.   va_list tags;
  311.   long ret;
  312.   va_start(tags, anchor); /* get parameter list */
  313.   ret = fplReset(anchor, (unsigned long *)tags);
  314.   va_end(tags)
  315.   return ret;
  316. }
  317.  
  318. long fplSendTags(void *anchor, ...)
  319. {
  320.   va_list tags;
  321.   long ret;
  322.   va_start(tags, anchor); /* get parameter list */
  323.   ret = fplSend(anchor, (unsigned long *)tags);
  324.   va_end(tags)
  325.   return ret;
  326. }
  327.  
  328. long fplAddFunctionTags(void *anchor, char *name, long ID, char rtrn,
  329.                         char *format, ...)
  330. {
  331.   va_list tags;
  332.   long ret;
  333.   va_start(tags, format); /* get parameter list */
  334.   ret = fplAddFunction(anchor, name, ID, rtrn, format, (unsigned long *)tags);
  335.   va_end(tags)
  336.   return ret;
  337. }
  338.  
  339. long fplReferenceTags(void *anchor, void *refID, ...)
  340. {
  341.   va_list tags;
  342.   long ret;
  343.   va_start(tags, format); /* get parameter list */
  344.   ret = fplReference(anchor, refID, (unsigned long *)tags);
  345.   va_end(tags)
  346.   return ret;
  347. }
  348.  
  349. #else /* VARARG_FUNCTIONS */
  350.  
  351. long fplExecuteScriptTags(void *anchor, char **program, long lines,
  352.                           unsigned long tags, ...)
  353. {
  354.   return(fplExecuteScript(anchor, program, lines, (unsigned long *)&tags));
  355. }
  356.  
  357. long fplExecuteFileTags(void *anchor, char *program, unsigned long tags, ...)
  358. {
  359.   return(fplExecuteFile(anchor, program, (unsigned long *)&tags));
  360. }
  361.  
  362. void *fplInitTags(long (*func)(struct fplArgument *), unsigned long tags, ...)
  363. {
  364.   return(fplInit(func, (unsigned long *)&tags));
  365. }
  366.  
  367. long fplResetTags(void *anchor, unsigned long tags, ...)
  368. {
  369.   return(fplReset(anchor, &tags));
  370. }
  371.  
  372. long fplSendTags(void *anchor, unsigned long tags, ...)
  373. {
  374.   return(fplSend(anchor, &tags));
  375. }
  376.  
  377. long fplAddFunctionTags(void *anchor, char *name, long ID, char rtrn,
  378.                         char *format, unsigned long tags, ...)
  379. {
  380.   return(fplAddFunction(anchor, name, ID, rtrn, format, &tags));
  381. }
  382.  
  383. long fplReferenceTags(void *anchor, void *refID, unsigned long tags, ...)
  384. {
  385.   return(fplReference(anchor, refID, &tags));
  386. }
  387.  
  388. #endif
  389.  
  390. #endif
  391.  
  392.  
  393. #define TEST_STRING "I_returned_this_from_the_interface_function!"
  394.  
  395. long ASM func(REG(a0) struct fplArgument *arg)
  396. {
  397.   int ret;
  398.   long col;
  399.   char *name;
  400.   char *string;
  401.   void *anchor=arg->key;
  402.   char systemline[80];
  403.   switch(arg->ID) {
  404.   case VR_TEST:
  405.     /* fplSendTags(anchor, FPLSEND_STRING, "internal variable!", FPLSEND_DONE); */
  406.     break;
  407.   case FN_TEST:
  408.     {
  409.       long new[2]={0,-1};
  410.       long *integer;
  411.       fplReferenceTags(anchor, arg->argv[0],
  412.                        FPLREF_NAME, &name,
  413.                FPLREF_TYPE, &col,
  414.                FPLREF_GET_STRING, &string,
  415.                FPLREF_GET_INTEGER, &integer,
  416.                FPLREF_DONE);
  417.       printf("Received a reference to the %s %svariable called '%s'\n",
  418.              col&FPLREF_TYPE_STRING?"string":"integer",
  419.              col&FPLREF_TYPE_ARRAY?"array ":"",
  420.              name);
  421.  
  422.       if(col&FPLREF_TYPE_ARRAY) {
  423.     struct fplRef ref;
  424.     fplReferenceTags(anchor, arg->argv[0],
  425.              FPLREF_ARRAY_INFO, &ref,
  426.              FPLREF_DONE);
  427.     if(1 == ref.Dimensions) {
  428.       long dims[]={0, -1};
  429.       for(col=0; col<ref.ArraySize[0]; col++) {
  430.         dims[0]=col;
  431.         fplReferenceTags(anchor, arg->argv[0],
  432.                  FPLREF_ARRAY_ITEM, &dims[0],
  433.                  FPLREF_GET_STRING, &name,
  434.                  FPLREF_DONE);
  435.         if(name[0])
  436.           printf("#%d: %s\n", col, name);
  437.       }
  438.       new[0] = 5;
  439.       fplReferenceTags(anchor, arg->argv[0],
  440.                FPLREF_ARRAY_ITEM, &dims[0],
  441.                FPLREF_SET_MY_STRING, "externally set",
  442.                FPLREF_DONE);
  443.           ref.ArraySize = new;
  444.           new[0] = 20;
  445.       fplReferenceTags(anchor, arg->argv[0],
  446.                            FPLREF_ARRAY_RESIZE, &ref,
  447.                FPLREF_DONE);
  448.     }
  449.       }
  450.       else if(col&FPLREF_TYPE_STRING) {
  451.         printf("It holds the string '%s'\n", string);
  452.     if(string=(char *)fplAllocString(anchor, strlen(TEST_STRING))) {
  453.           strcpy(string, TEST_STRING);
  454.       fplReferenceTags(anchor, arg->argv[0],
  455.                        FPLREF_SET_STRING, string,
  456.                    FPLREF_END);
  457.       fplReferenceTags(anchor, arg->argv[0],
  458.                        FPLREF_SET_MY_STRING, TEST_STRING,
  459.                    FPLREF_END);
  460.     }
  461.       } else if(col&FPLREF_TYPE_INTEGER) {
  462.         printf("It holds the number %d\n", *integer);      
  463.       }
  464.     }
  465.     break;
  466.  
  467.   case FN_PRINTF:
  468. #if defined(AMIGA)
  469.     vprintf(arg->argv[0], (char *)&arg->argv[1]);
  470. #elif defined(UNIX)
  471.     vfprintf(stderr, arg->argv[0], (char *)&arg->argv[1]);
  472. #endif
  473.     break;
  474.   case FN_OUTPUT: /* output */
  475.     if(arg->format[0]==FPL_STRARG)  /* we got a string! */
  476.       string="%s";
  477.     else
  478.       string="%d";
  479. #if defined(AMIGA)
  480.     printf(string, arg->argv[0]);
  481. #elif defined(UNIX)
  482.     fprintf(stderr, string, arg->argv[0]);
  483. #endif
  484.     fplSendTags(anchor, FPLSEND_INT, 1, FPLSEND_DONE);
  485.     break;
  486.     
  487.   case FN_GETSTRING:
  488.     if(string=(char *)fplAlloc(anchor, 64)) {
  489.       if(arg->argc)
  490.     printf("%s", arg->argv[0]);
  491.       fgets(string, 64, stdin);
  492.       ret=fplSendTags(arg->key,
  493.               FPLSEND_STRING, string,
  494.               FPLSEND_STRLEN, strlen(string)-1,
  495.               FPLSEND_DONE);
  496.       fplDealloc(anchor, string);
  497.     } else
  498.       ret=FPLERR_OUT_OF_MEMORY;
  499.     return(ret);
  500.  
  501.   case FN_EXECUTE:
  502.     ret=fplExecuteFile(anchor, arg->argv[0], NULL);
  503.     return(ret);
  504.     break;
  505.  
  506.   case FPL_GENERAL_ERROR:
  507.     {
  508.       char buffer[FPL_ERRORMSG_LENGTH];
  509.       fplSendTags(anchor,
  510.           FPLSEND_GETVIRLINE, &col,
  511.           FPLSEND_GETVIRFILE, &name,
  512.           FPLSEND_DONE);
  513.       if(*name=='\"') {
  514.     ret=0;
  515.     name++;
  516.     while(name[ret] && name[ret]!='\"')
  517.       ret++;
  518.     string=(char *)fplAlloca(anchor, ret+1);
  519.     memcpy(string, name, ret);
  520.     string[ret]='\0';
  521.       } else {
  522.     string=name;
  523.     ret=0;
  524.       }
  525.       printf("\n>>> %s\n",
  526.          fplGetErrorMsg(arg->key, (long)arg->argv[0], buffer));
  527.       printf(">>> Line %d in file \"%s\". <<<\n", col, string);
  528.       if(ret)
  529.     fplDealloca(anchor, string);
  530.     }
  531.     break;
  532.  
  533.   case FPL_UNKNOWN_FUNCTION:
  534.     col=22; /* only to breakpoint */
  535.     break;
  536.  
  537.   case FN_GETINT:
  538.     if(arg->argc)
  539.       printf("%s", (char *)arg->argv[0]);
  540.     scanf("%d", &ret);
  541.     ret=fplSendTags(anchor, FPLSEND_INT, ret, FPLSEND_DONE);
  542.     return(ret);
  543.   }
  544.   return FPL_OK;
  545. }
  546.  
  547. long ASM inter(REG(a0) void *count)
  548. {
  549.   static line=-1;
  550. #if 0
  551.   static char *name;
  552.   long current_line;
  553.   char *curr_name;
  554.  
  555.   fplSendTags(key, FPLSEND_GETVIRLINE, ¤t_line, FPLSEND_DONE);
  556.   fplSendTags(key, FPLSEND_GETVIRFILE, &curr_name, FPLSEND_DONE);
  557.   if(line!=current_line || name != curr_name) {
  558.     line=current_line;
  559.     name=curr_name;
  560. /*    fprintf(stderr, " < %d %s > ", line, name?name:"unknwon"); */
  561.   }
  562. #endif
  563.  
  564.   (*(int *)count)++; /* just to count the number of times this routine has been
  565.             called. */
  566.   return(0);
  567. }
  568.  
  569. void CALLER ASM MyFree(REG(a1) void *pntr, REG(d0) long size)
  570. {
  571.   memory_counter-=size;
  572.   memset(pntr, 0xaa, size); /* mess up this area before free! */
  573.   free(pntr);
  574. }
  575.  
  576. void CALLER ASM *MyAlloc(REG(d0) long size)
  577. {
  578.   void *mem;
  579.   mallocs++;
  580.   if((memory_counter+=size)>maxmemory_counter)
  581.     maxmemory_counter=memory_counter;
  582. #ifdef UNIX
  583.   mem=malloc(size);
  584. #else
  585.   mem=AllocMem(size, 0);
  586. #endif
  587.   if(mem)
  588.     memset(mem, 0xaa, size); /* mess up this area before free! */
  589.   return (mem);
  590. }
  591.